﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace FriendlyFire.UserControls
{
    public partial class ConfigOptions : Form
    {
        //vars
        private FriendlyFire myParent;
        private string _privKeyHolder = "";

        /* KEYS
         * 
         * displayname
         * bggradientcolor
         * personalkey
         * privatekey
         * saveto
         */
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ffHelper">Reference to friendly fire helper</param>
        public ConfigOptions(FriendlyFire parent)
        {
            InitializeComponent();
            myParent = parent;
            // adds the keyUp event to every control
            // so pressing esc works everywhere in the
            // dialog
            foreach (Control c in this.Controls)
            {
                c.KeyUp += new KeyEventHandler(c_KeyUp);
            }
        }

        #region c_Keyup
        /// <summary>
        /// CustomKeyUp event for the form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void c_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.DialogResult = DialogResult.Cancel;
                this.Close();
            }
            if (e.KeyCode == Keys.Enter)
            {
                this.btnSaveClose_Click(null, null);
            }
        }
        #endregion

        #region save and close
        /// <summary>
        /// Saves all form data and closes the form with
        /// a DialogResult of OK.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSaveClose_Click(object sender, EventArgs e)
        {
            // Save shit Here
            myParent.ffHelper.DBHelper.SetConfig("displayname", txtDisplayName.Text.Trim());
            myParent.ffHelper.DBHelper.SetConfig("bggradientcolor", cmbColor.SelectedItem.ToString());
            myParent.ffHelper.CurrentGradientColor = Color.FromName(cmbColor.SelectedItem.ToString());
            myParent.ffHelper.DBHelper.SetConfig("saveto", txtDir.Text.Trim());
            myParent.ffHelper.DBHelper.SetConfig("personalkey", txtMyKey.Text);
            myParent.ffHelper.DBHelper.SetConfig("privatekey", _privKeyHolder);

            this.DialogResult = DialogResult.OK;
            myParent.Trans.UpdateGrid();
            this.Close();
        }
        #endregion

        /// <summary>
        /// Cancel event, closes the form
        /// </summary>
        /// <param name="sender">Object sending the event</param>
        /// <param name="e">any event arguments that need to be passed</param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        #region ConfigOptions_Load
        /// <summary>
        /// Prepares the config screen. Takes into account
        /// the occurence where the user has never edited the options
        /// and we are relying on defaults.
        /// </summary>
        /// <param name="sender">Object sending the event</param>
        /// <param name="e">any event arguments that need to be passed</param>
        private void ConfigOptions_Load(object sender, EventArgs e)
        {
            cmbColor.Items.Clear();
            cmbColor.Items.AddRange(GetColors().ToArray()); // loads ALL "known" colors


            //TODO make default value system if these do not exist.
            txtDisplayName.Text = myParent.ffHelper.DBHelper.GetConfig("displayname");
            cmbColor.SelectedIndex = cmbColor.Items.IndexOf(myParent.ffHelper.DBHelper.GetConfig("bggradientcolor"));
            txtMyKey.Text = myParent.ffHelper.DBHelper.GetConfig("personalkey");
            _privKeyHolder = myParent.ffHelper.DBHelper.GetConfig("privatekey");
            txtDir.Text = myParent.ffHelper.DBHelper.GetConfig("saveto");
            folderBrowserDialog1.SelectedPath = myParent.ffHelper.DBHelper.GetConfig("saveto");
        }
        #endregion


        #region newkeyclick
        /// <summary>
        /// Creates a new personal key for the user.
        /// </summary>
        /// <param name="sender">Object sending the event</param>
        /// <param name="e">any event arguments that need to be passed</param>
        private void btnNewKey_Click(object sender, EventArgs e)
        {
            //  Make the new key here and assign to myNewKey
            //
            DialogResult dr = MessageBox.Show("Warning, changing your private key will invalidate all existing friends.",
                                              "Are you sure?",
                                              MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                btnNewKey.Text = "Please Wait...";
                btnNewKey.Enabled = false;
                // TODO delete old friends when generating new key like before.
                //SubSonic.Generated.FriendXController con = new SubSonic.Generated.FriendXController();
                //SubSonic.Generated.FriendXCollection friendsToKill = con.FetchAll();
                //foreach (SubSonic.Generated.FriendX f in friendsToKill)
                //{
                //    con.Delete(f.Id);
                //}
                using (RSACryptoServiceProvider myKey = new RSACryptoServiceProvider(4096))
                {
                    txtMyKey.Text = myKey.ToXmlString(false);
                    _privKeyHolder = myKey.ToXmlString(true);
                    myKey.Clear();
                }
                //myParent.Home.UpdateHomeDashboardFriendsList();
                btnNewKey.Enabled = true;
                btnNewKey.Text = "Generate New Key";
            }
        }
        #endregion


        #region get colors
        /// <summary>
        /// Enumerates ALL dotnet "known colors"
        /// </summary>
        /// <returns></returns>
        private List<string> GetColors()
        {
            //create a generic list of strings
            List<string> colors = new List<string>();
            //get the color names from the Known color enum
            string[] colorNames = Enum.GetNames(typeof(KnownColor));
            //iterate thru each string in the colorNames array
            foreach (string colorName in colorNames)
            {
                //cast the colorName into a KnownColor
                KnownColor knownColor = (KnownColor)Enum.Parse(typeof(KnownColor), colorName);
                //check if the knownColor variable is a System color
                if (knownColor > KnownColor.Transparent)
                {
                    //add it to our list
                    colors.Add(colorName);
                }
            }
            //return the color list
            return colors;
        }
        #endregion

        private void ConfigOptions_Paint(object sender, PaintEventArgs e)
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            myParent.ffHelper.DrawDefaultBackGroundGradient(e.Graphics, ClientRectangle);
        }

        private void btnChooseDir_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                txtDir.Text = folderBrowserDialog1.SelectedPath;
            }
        }
    }
}
